import { isObjectNotEmpty, isShallowEqual } from './object';
import { isIE, isValidURL } from './browser';
import {
  isEmojiCharacter,
  isNumber,
  isSpecialCharacters,
  isStringNotEmpty,
  isStringNotEmptyOrWhiteSpace,
} from './string';

/**
 * 统一校验函数包裹层， 额外为包裹的校验函数包裹一个必填参数（校验异常的提示信息）
 * @param 以包裹的函数为准按顺序传
 * @param string 校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
 **/
const validatorWrapper =
  <F extends (...args: any[]) => boolean>(f: F) =>
  (...args: [...Parameters<F>, string]) => {
    const message = args.pop();
    return Validator.expression(f(...args), message);
  };

export class Validator {
  /**
   * 统一校验，当判断失败且有message时，抛出message异常
   * @param exp
   * @param message
   * @returns
   */
  static expression(exp: boolean, message: string = undefined) {
    if (!exp && message) {
      throw message;
    }
    return exp;
  }

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isIE = validatorWrapper(isIE);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isShallowEqual = validatorWrapper(isShallowEqual);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isNumber = validatorWrapper(isNumber);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isSpecialCharacters = validatorWrapper(isSpecialCharacters);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isEmojiCharacter = validatorWrapper(isEmojiCharacter);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isObjectNotEmpty = validatorWrapper(isObjectNotEmpty);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isStringNotEmpty = validatorWrapper(isStringNotEmpty);

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isStringNotEmptyOrWhiteSpace = validatorWrapper(
    isStringNotEmptyOrWhiteSpace,
  );

  /**
   * @param string 参数列表最后的值为校验异常的提示信息：传假值（空字符串、undefined等）则在校验出错是返回原判断函数的值，否则抛出此信息
   */
  static isValidURL = validatorWrapper(isValidURL);
}

export default Validator;
